/**
 * 
 */
package com.googlecode.pcapj;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.bridj.Pointer;

import com.googlecode.pcapj.bridj.Wpcap;
import com.googlecode.pcapj.bridj.pcap_addr;
import com.googlecode.pcapj.bridj.pcap_if;

/**
 * 
 */
class InterfaceImpl extends PacketCaptureImpl implements Interface{
	private static final int DEFAULT_SNAPLEN = 65535; 
	
	private String name;
	private String description;
	private boolean loopback;
	private List<SocketInfo> socketInfos = new ArrayList<SocketInfo>();
	
	
	/**
	 * @param defaultDataLinkLayer
	 * @param dataLinkLayers
	 */
	InterfaceImpl(
			pcap_if pcap_if, CapturedFactory capturedFactory) {
		super(capturedFactory);
		name = toCString(pcap_if.name());
		description = toCString(pcap_if.description());
		loopback = (pcap_if.flags() & Wpcap.PCAP_IF_LOOPBACK) != 0;
		Pointer<pcap_addr> pPcap_addr = pcap_if.addresses();
		while(pPcap_addr != Pointer.NULL){
			pcap_addr pcap_addr = pPcap_addr.get();
			socketInfos.add(new SocketInfoImpl(pcap_addr));
			pPcap_addr = pcap_addr.next();
		}
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.Interface#getName()
	 */
	public String getName() {
		return name;
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.Interface#getDescription()
	 */
	public String getDescription() {
		return description;
	}
	
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.Interface#isLoopback()
	 */
	public boolean isLoopback() {
		return loopback;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.Interface#getSocketInfos()
	 */
	public List<SocketInfo> getSocketInfos() {
		return Collections.unmodifiableList(socketInfos);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.Interface#setFilter(java.lang.String)
	 */
	public void setFilter(String filterString) throws IOException {
		int netmask = 0xffffff;
		if(socketInfos.size() > 0){
			netmask = 0;
			InetAddress inetAddress = socketInfos.get(0).getNetmask().getInetAddress();
			if(inetAddress != null){
				byte[] address = inetAddress.getAddress();
				netmask = 
						(address[0] << 24) | 
						(address[1] << 16) | 
						(address[2] <<  8) | 
						(address[3] );
			}
		}
		getPcapWrapper().setFilter(filterString, netmask);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.PacketCaptureImpl#getDefaultSnapLength()
	 */
	@Override
	int getDefaultSnapLength() {
		return DEFAULT_SNAPLEN;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.PacketCaptureImpl#getDefaultTimeout()
	 */
	@Override
	int getDefaultTimeout() {
		return 0;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.PacketCaptureImpl#getSourceName()
	 */
	@Override
	String getSourceName() {
		return getName();
	}
	private static String toCString(Pointer<?> pointer){
		String string = null;
		if(pointer != null){
			string = pointer.getCString();
		}
		return string;
	}
}
